/**
* copyright (c) 2017-2023 厦门风领科技有限公司
* https://www.fengling.cn/
* 
* 广告基类
* zengbinsi
* 2022-03-01 21:44:26
* 2023-10-23 15:31:53
*/
console.log('[TS-API] ===>>>', 'Load class ADBase.');
window.gg = window.gg || {};

if (cc.sys.isNative) {
    class ADBase {

        constructor(adType, data) {
            this.data = data || {};
            this.data.extData = `CLSID_${adType}_${Date.now()}${Math.floor(Math.random() * 10000)}`;
            this.data.adType = adType;

            this.loadCallbacks = [];
            this.errorCallbacks = [];
            this.closeCallbacks = [];
            this.clickCallbacks = [];

            this.promiseLoadCallbacks = {};
            this.promiseShowCallbacks = {};

            this.initData && this.initData();
            gg.jsb.emitEventAD({ adEventType: 'CREATE', ...this.data });

            ADBase.ad[this.data.extData] = this;
        }

        load() {
            return new Promise((resolve, reject) => {
                const callback = `load_${this.data.extData}`;
                this.promiseLoadCallbacks[callback] = (err, res) => {
                    this.promiseLoadCallbacks[callback] = undefined;
                    if (err) { return reject(err); }

                    resolve(res);
                };

                gg.jsb.emitEventAD({ adEventType: 'LOAD', ...this.data });
            });
        }

        show() {
            gg.log(`===>>>显示${this.data.adType}广告`);
            return new Promise((resolve, reject) => {
                const callback = `show_${this.data.extData}`;
                this.promiseShowCallbacks[callback] = (err, res) => {
                    this.promiseShowCallbacks[callback] = undefined;
                    if (err) { return reject(err); }

                    resolve(res);
                };

                gg.jsb.emitEventAD({ adEventType: 'SHOW', ...this.data });
            });
        }

        destroy() {
            ADBase.ad[this.data.extData] = undefined;
            gg.log('原生视频不做销毁');
        }



        onLoad(callback) {
            this.loadCallbacks.push(callback);
        }

        offLoad(callback) {
            var index = this.loadCallbacks.indexOf(callback);
            if (index !== -1) {
                this.loadCallbacks.splice(i, 1);
            }
        }

        onError(callback) {
            this.errorCallbacks.push(callback);
        }

        offError(callback) {
            var index = this.errorCallbacks.indexOf(callback);
            if (index !== -1) {
                this.errorCallbacks.splice(i, 1);
            }
        }

        onClose(callback) {
            this.closeCallbacks.push(callback);
        }

        offClose(callback) {
            var index = this.closeCallbacks.indexOf(callback);
            if (index !== -1) {
                this.closeCallbacks.splice(i, 1);
            }
        }

        onClick(callback) {
            this.clickCallbacks.push(callback);
        }

        offClick(callback) {
            var index = this.clickCallbacks.indexOf(callback);
            if (index !== -1) {
                this.clickCallbacks.splice(i, 1);
            }
        }




        static onCreatedCallback(data) {
            gg.log('onCreatedCallback', data);
        }

        static onShowedCallback(data) {
            gg.log('onShowedCallback', data);
            data = gg.parseJSON(data);
            if (!data || !data.extData) { return; }

            const ad = ADBase.ad[data.extData];
            for (let key in ad.promiseShowCallbacks) {
                ad.promiseShowCallbacks[key] && ad.promiseShowCallbacks[key](null, data);
            }
        }

        static onShowFailedCallback(data) {
            gg.log('onShowFailedCallback', data);
            data = gg.parseJSON(data);
            if (!data || !data.extData) { return; }

            const ad = ADBase.ad[data.extData];
            for (let key in ad.promiseShowCallbacks) {
                ad.promiseShowCallbacks[key] && ad.promiseShowCallbacks[key](data);
            }
        }

        static onPlayVideoFailedCallback(data) {
            gg.log('onPlayVideoFailedCallback', data);
            data = gg.parseJSON(data);
            if (!data || !data.extData) { return; }

            const ad = ADBase.ad[data.extData];
            for (let key in ad.promiseShowCallbacks) {
                ad.promiseShowCallbacks[key] && ad.promiseShowCallbacks[key](data);
            }
        }

        static onPlayVideoStartedCallback(data) {
            gg.log('onPlayVideoStartedCallback', data);
            data = gg.parseJSON(data);
            if (!data || !data.extData) { return; }

            const ad = ADBase.ad[data.extData];
            for (let key in ad.promiseShowCallbacks) {
                ad.promiseShowCallbacks[key] && ad.promiseShowCallbacks[key](null, data);
            }
        }
        static onPlayEndedCallback(data) {
            gg.log('onPlayEndedCallback', data);
        }
        static onRewardedCallback(data) {
            gg.log('onRewardedCallback', data);
        }

        static onLoadedCallback(data) {
            gg.log('onLoadedCallback', data);
            data = gg.parseJSON(data);
            if (!data || !data.extData) { return; }

            var ad = ADBase.ad[data.extData];
            for (let key in ad.promiseLoadCallbacks) {
                ad.promiseLoadCallbacks[key] && ad.promiseLoadCallbacks[key](null, data);
            }
            for (let i = 0; i < ad.loadCallbacks.length; i++) {
                ad.loadCallbacks[i]();
            }
        }

        static onLoadFailedCallback(data) {
            gg.log('onLoadFailedCallback', data);
            data = gg.parseJSON(data);
            if (!data || !data.extData) { return; }

            const ad = ADBase.ad[data.extData];
            for (let key in ad.promiseLoadCallbacks) {
                ad.promiseLoadCallbacks[key](data);
            }

            ADBase.onErrorCallback(data);
        }

        static onClosedCallback(data) {
            gg.log('onClosedCallback', data);
            data = gg.parseJSON(data);
            if (!data || !data.extData) { return; }

            var ad = ADBase.ad[data.extData];
            var res = { isEnded: data.isEnded };

            for (let i = 0; i < ad.closeCallbacks.length; i++) {
                ad.closeCallbacks[i](res);
            }
        }

        static onClickedCallback(data) {
            gg.log('onClickedCallback', data);
            data = gg.parseJSON(data);
            if (!data || !data.extData) { return; }

            var ad = ADBase.ad[data.extData];
            var res = { isEnded: data.isEnded };

            for (let i = 0; i < ad.clickCallbacks.length; i++) {
                ad.clickCallbacks[i](res);
            }
        }

        static onErrorCallback(data) {
            gg.log('onErrorCallback', data);
            data = gg.parseJSON(data);
            if (!data || !data.extData) { return; }

            var ad = ADBase.ad[data.extData];
            var err = { errMsg: data.errMsg || "原生层返回错误", errCode: data.errCode || 1003 };

            for (let i = 0; i < ad.errorCallbacks.length; i++) {
                ad.errorCallbacks[i](err);
            }
        }
    }

    ADBase.ad = {};
    window.ADBase = ADBase;

    class RewardedVideoAd extends ADBase {
        constructor(data) {
            super('REWARDED', data);
        }
    }

    class InterstitialAd extends ADBase {
        constructor(data) {
            super('INTERSTITIAL', data);
        }
    }

    class BannerAd extends ADBase {
        constructor(data) {
            super('BANNER', data);
        }

        initData() {
            this.data.style = this.data.style || {};
            this.data.bannerStyle = this.data.style;

            this.loadTime = Math.floor(Date.now() / 1000);
        }

        load() {
            // 原生平台Banner加载间隔要超过10s
            if (Math.floor(Date.now() / 1000) - (this.loadTime || 0) < 11) { return; }
            this.loadTime = Math.floor(Date.now() / 1000);

            gg.jsb.emitEventAD({ adEventType: 'LOAD', ...this.data });
        }

        hide() {
            gg.log('=====>>>隐藏BannerAd广告');
            gg.jsb.emitEventAD({ adEventType: 'HIDE', ...this.data });
        }

        destroy() {
            ADBase.ad[this.data.extData] = undefined;
            gg.jsb.emitEventAD({ adEventType: 'DESTROY', ...this.data });
        }
    }

    window.RewardedVideoAd = RewardedVideoAd;
    window.InterstitialAd = InterstitialAd;
    window.BannerAd = BannerAd;
}